#include "soucoupe.h"
#include "neon.h"
#include <cmath>
#include <list>

/***********************************/
/*** Constructeurs / Destructeur ***/
/***********************************/

Soucoupe::Soucoupe():RevolutionObject(40,2*M_PI),_cockpit(NULL),_pilote(NULL),_fond(NULL)
{

_generatePoints(2*M_PI);
_cockpit  = new Cockpit();
_cockpit->setPosition(0.0,2.0,0.0);
_tex = new Texture("soucoupe.jpg");
setMaterial(MaterialCreator::createChrome());
//_fond = new Plan(3.0,3.0,"fond.png");
}

bool Soucoupe::animationOn=false;
int Soucoupe::_id=0;
Soucoupe::Soucoupe(Vent *vent):RevolutionObject(40,2*M_PI),_pilote(NULL),_fond(NULL)
{
_generatePoints(2*M_PI);
_cockpit  = new Cockpit();
_cockpit->setPosition(0.0,2.0,0.0);
_tex = new Texture("soucoupe.jpg");
//_tex->setModePlaquage(GL_REPLACE);
Material *m = new  Material();
m->setDiffuse(1.0,1.0,1.0,1.0);
m->setAmbient(1.0,1.0,1.0,1.0);
m->setShininess(5);
setMaterial(m);
//_fond= new Plan(3.0,3.0,"fond.png");
//setMaterial(MaterialCreator::createChrome());

_duree = 375; //30 seconde d'animation
_compteur=0;
if(vent)
{
  if(_id==0)
  {
     _traj = new TrajectoireSoucoupe1(vent);
     _myId=_id;
     _id++;
  }
  else 
  {
    _traj = new TrajectoireSoucoupe2(vent);
  }
  _traj->initTrajectoire(_duree);
  float x,y,z;
  _traj->calculerPoint(x,y,z,_compteur);
  setPosition(x,y,z); _fumee = new Fumee(vent);
  cout << _xArrivee << " " << _zArrivee << endl;
  _fumee->setPosition(_xArrivee, -0.5, _zArrivee);
  if(_scene) _scene->addObjet(_fumee);
}
else
{
  _traj=NULL;
  _fumee=NULL;
}
 _fumeeOn=false;
}

Soucoupe::~Soucoupe()
{
if (_cockpit)
  delete _cockpit;
if (_tex)
  delete _tex;
if(_pilote)
  delete _pilote;
if(_fond)
  delete _fond;
}


/***************************/
/**** Getters / Setters ****/
/***************************/

void Soucoupe::setPilote(const char * s)
{
	if(_pilote)
		delete _pilote;

_pilote = new Plan(2.0,2.0,s);
_pilote->setPosition(0.0,3.0,0.0);

}


bool Soucoupe::addNeon(Neon *objet)
{
  _neons.push_back(objet);
  return true;
}

bool Soucoupe::removeNeon(Neon *objet)
{
  _neons.remove(objet);
  return true;
}

void Soucoupe::setScene(Scene *s)
{
  Objet3D::setScene(s);
  if (_cockpit)
  _cockpit->setScene(s);
  if(_pilote)
	  _pilote->setScene(s);
  genNeons(5);
  if(_fumee) _fumee->setScene(s);
  s->addObjet(_fumee);
}

void Soucoupe::setPosition(float x, float y, float z)
{
float a,b,c,d,e,f,dx,dy,dz;
getPosition(a,b,c);
for (list<Neon*>::iterator it = _neons.begin();it != _neons.end();it++)
{
	(*it)->getPosition(d,e,f);
	dx = d-a;
	dy = e-b;
	dz = f-c;
	(*it)->setPosition(x+dx,y+dy,z+dz);
}

Objet::setPosition(x,y,z);
}



/**********************************/
/*** Fonctions d'initialisation ***/
/**********************************/

void Soucoupe::genNeons(int number)
{
float x,y,z;
getPosition(x,y,z);
//Creation du materiau

  //Lumieres du neon
   Lumiere * lumNeon;
   Lumiere * lumNeon2;

  //Materiaux du neon (transparent)
  Material * mNeon;
  Material * mNeon2;
  Material * mNeon3;
  //placage des neons
  Neon * n;

  double angle = 2*M_PI/number;
for (int i =0;i<number;i++)
{

lumNeon = new Lumiere();
   lumNeon->setDiffuse(1.0,0.0,0.0,0.5);
   lumNeon->setAmbient(1.0,0.0,0.0,0.1);
   lumNeon->setCutoff(45.0);
   lumNeon->setDirection(0.0,1.0,0.0); 
//   lumNeon2 = new Lumiere();
//   lumNeon2->setDiffuse(1.0,1.0,1.0,0.1);
//   lumNeon2->setAmbient(1.0,0.1,0.1,0.1);

mNeon = new Material();
    mNeon->setDiffuse(1.0,0.0,0.0,0.3);
    mNeon->setEmissive(1.0,0.3,0.0,0.3);
    mNeon->setShininess(0);

mNeon2 = new Material();
    mNeon2->setDiffuse(1.0,1.0,1.0,0.3);
    mNeon2->setEmissive(1.0,0.8,0.0,0.4);
 //   mNeon->setSpecular(1.0,0.0,0.0,0.1);
    mNeon->setShininess(0);

mNeon3 = new Material();
    mNeon3->setDiffuse(1.0,0.0,0.0,0.3);
    mNeon3->setEmissive(0.8,0.8,0.8,0.5);
    mNeon3->setShininess(0);

n = new Neon(1.0);
addNeon(n);
n->setLumiere(lumNeon);
//n->setLumiere2(lumNeon2);
n->setMaterial(mNeon);
n->setMaterial2(mNeon2);
n->setMaterial3(mNeon3);
//old value 4.0
n->setPosition(x+4.0*cos(angle*i),y-1.0,z+4.0*sin(angle*i));
getScene()->addNeon(n);
}
}


list<Vertex> Soucoupe::_generateProfil()
{
list<Vertex> profil;
profil.push_back(Vertex(0.0,2.0,0.0,0.0,0.1,0.1,0.1));
profil.push_back(Vertex(3.0,2.0,0.0,0.0,0.1,0.1,0.1));
profil.push_back(Vertex(3.5,1.5,0.0,0.0,0.1,0.1,0.1));
profil.push_back(Vertex(7.0,0.5,0.0,0.0,0.1,0.1,0.1));
profil.push_back(Vertex(7.0,-0.5,0.0,1.0,0.1,0.1,0.1));
profil.push_back(Vertex(3.5,-1.5,0.0,1.0,0.1,0.1,0.1));
profil.push_back(Vertex(3.0,-2.0,0.0,1.0,0.1,0.1,0.1));
profil.push_back(Vertex(0.0,-2.0,0.0,1.0,0.1,0.1,0.1));

return profil;
}


/****************************/
/********* Callbacks ********/
/****************************/

void Soucoupe::onTimerEvent(int)
{
    _animeTexture();
  if(_traj && _compteur <= _duree && animationOn)
  {
    float x,y,z;
    _traj->calculerPoint(x,y,z,_compteur);
    setPosition(x,y,z);
    if(((float)_compteur)/_duree >=0.80 && _fumeeOn==false && _myId == 0)
    {
//      _scene->addObjet(_fumee);
      _fumee->setActive(true);
      _fumeeOn=true;
    }
    if(_fumeeOn)
    {
      _fumee->setPosition(x, -1.0, z);
    }
    _compteur++;
  }
  else
  {
    animationOn=false;
    _fumeeOn=false;
//    _scene->removeObjet(_fumee);
      _fumee->setActive(false);
    _compteur=0;
  }
  Scene::clignChange();
}


//le decalage de la texture se situe entre les lignes 112 et 142
void Soucoupe::_animeTexture()
{
  unsigned char *data = (_tex->getImage())->data;
  unsigned char *debut = new unsigned char[3*6];

  for(int j=0; j<6; j++)
  {
    *(debut + j*3) = *(data + (125+j)*256*4);
    *(debut + 1 + j*3) = *(data + 1 + (125 + j)*256*4);
    *(debut + 2 + j*3) = *(data + 2 + (125 + j)*256*4);
  }
  
  for(int i=0; i<255; i++)
  {
    for(int j=125; j<=130; j++)
    {
      *(data + i*4 + j*256*4) = *(data + ((i+1)*4) + j*256*4);
      *(data + i*4+1 + j*256*4) = *(data + ((i+1)*4+1) + j*256*4);
      *(data + i*4+2  + j*256*4) = *(data + ((i+1)*4+2) + j*256*4);
    }
  }
  for(int j=125; j<=130; j++)
  {
    *(data + 255*4 + j*256*4) = *(debut + (j-125)*3);
    *(data + 255*4 + 1 + j*256*4) = *(debut + 1 + (j-125)*3);
    *(data + 255*4 + 2 + j*256*4) = *(debut + 2 + (j-125)*3);
  }

  delete[] debut;
}



/**********************************/
/******* Fonction de dessin *******/
/**********************************/

void Soucoupe::_draw()
{
  glScalef(0.3333,0.3333,0.3333);
  RevolutionObject::_draw();

//  if (_pilote)
//	  _pilote->display();
  if(_cockpit)
  _cockpit->display();
float a,b,c;
getPosition(a,b,c);
glTranslatef(-a,-b,-c);


_neons.sort(Scene::plusEloigne);
for (list<Neon*>::iterator it = _neons.begin();it != _neons.end(); it++)
  {
	  (*it)->irradiate();
	(*it)->display();
  }

}

